home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / security / shadow-3.1.4 / getpass.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-26  |  3.3 KB  |  171 lines

  1. /*
  2.  * Copyright 1990, 1991, John F. Haugh II
  3.  * All rights reserved.
  4.  *
  5.  * Permission is granted to copy and create derivative works for any
  6.  * non-commercial purpose, provided this copyright notice is preserved
  7.  * in all copies of source code, or included in human readable form
  8.  * and conspicuously displayed on all copies of object code or
  9.  * distribution media.
  10.  */
  11.  
  12. #include <signal.h>
  13. #include <stdio.h>
  14. #include "config.h"
  15.  
  16. #ifdef    BSD
  17. #include <sgtty.h>
  18. #include <strings.h>
  19. #else
  20. #include <termio.h>
  21. #include <string.h>
  22. #endif
  23.  
  24. #ifndef    lint
  25. static    char    sccsid[] = "@(#)getpass.c    3.7    08:27:22    10/31/91";
  26. #endif
  27.  
  28. /*
  29.  * limits.h may be kind enough to specify the length of a prompted
  30.  * for password.
  31.  */
  32.  
  33. #if __STDC__ || _POSIX_SOURCE
  34. #include <limits.h>
  35. #endif
  36.  
  37. /*
  38.  * This is really a giant mess.  On the one hand, it would be nice
  39.  * if PASS_MAX were real big so that DOUBLESIZE isn't needed.  But
  40.  * if it is defined we must honor it because some idiot might use
  41.  * this in a routine expecting some standard behavior.
  42.  */
  43.  
  44. #ifndef    PASS_MAX
  45. #ifdef    DOUBLESIZE
  46. #define    PASS_MAX    16
  47. #else
  48. #define    PASS_MAX    8
  49. #endif
  50. #endif
  51.  
  52. #ifdef    BSD
  53. #define    STTY(fd,termio)    stty(fd, termio)
  54. #define    GTTY(fd,termio) gtty(fd, termio)
  55. #define    TERMIO    struct    sgttyb
  56. #define    INDEX    index
  57. #else
  58. #define    STTY(fd,termio) ioctl(fd, TCSETA, termio)
  59. #define    GTTY(fd,termio) ioctl(fd, TCGETA, termio)
  60. #define    TERMIO    struct    termio
  61. #define    INDEX    strchr
  62. #endif
  63.  
  64. static    int    sig_caught;
  65.  
  66. static void
  67. sig_catch ()
  68. {
  69.     sig_caught = 1;
  70. }
  71.  
  72. char *
  73. getpass (prompt)
  74. char    *prompt;
  75. {
  76.     static    char    input[PASS_MAX+1];
  77.     char    *return_value = 0;
  78.     char    *cp;
  79.     FILE    *fp;
  80.     int    tty_opened = 0;
  81.     SIGTYPE    (*old_signal)();
  82.     TERMIO    new_modes;
  83.     TERMIO    old_modes;
  84.  
  85.     /*
  86.      * set a flag so the SIGINT signal can be re-sent if it
  87.      * is caught
  88.      */
  89.  
  90.     sig_caught = 0;
  91.  
  92.     /*
  93.      * if /dev/tty can't be opened, getpass() needs to read
  94.      * from stdin instead.
  95.      */
  96.  
  97.     if ((fp = fopen ("/dev/tty", "r")) == 0) {
  98.         fp = stdin;
  99.         setbuf (fp, (char *) 0);
  100.     } else {
  101.         tty_opened = 1;
  102.     }
  103.  
  104.     /*
  105.      * the current tty modes must be saved so they can be
  106.      * restored later on.  echo will be turned off, except
  107.      * for the newline character (BSD has to punt on this)
  108.      */
  109.  
  110.     if (GTTY (fileno (fp), &new_modes))
  111.         return 0;
  112.  
  113.     old_modes = new_modes;
  114.     old_signal = signal (SIGINT, sig_catch);
  115.  
  116. #ifdef    BSD
  117.     new_modes.sg_flags &= ~ECHO ;
  118. #else
  119.     new_modes.c_lflag &= ~(ECHO|ECHOE|ECHOK);
  120.     new_modes.c_lflag |= ECHONL;
  121. #endif
  122.  
  123.     if (STTY (fileno (fp), &new_modes))
  124.         goto out;
  125.  
  126.     /*
  127.      * the prompt is output, and the response read without
  128.      * echoing.  the trailing newline must be removed.  if
  129.      * the fgets() returns an error, a NULL pointer is
  130.      * returned.
  131.      */
  132.  
  133.     if (fputs (prompt, stdout) == EOF)
  134.         goto out;
  135.  
  136.     (void) fflush (stdout);
  137.  
  138.     if (fgets (input, sizeof input, fp) == input) {
  139.         if (cp = INDEX (input, '\n'))
  140.             *cp = '\0';
  141.         else
  142.             input[sizeof input - 1] = '\0';
  143.  
  144.         return_value = input;
  145. #ifdef    BSD
  146.         putc ('\n', stdout);
  147. #endif
  148.     }
  149. out:
  150.     /*
  151.      * the old SIGINT handler is restored after the tty
  152.      * modes.  then /dev/tty is closed if it was opened in
  153.      * the beginning.  finally, if a signal was caught it
  154.      * is sent to this process for normal processing.
  155.      */
  156.  
  157.     if (STTY (fileno (fp), &old_modes))
  158.         return_value = 0;
  159.  
  160.     (void) signal (SIGINT, old_signal);
  161.  
  162.     if (tty_opened)
  163.         (void) fclose (fp);
  164.  
  165.     if (sig_caught) {
  166.         kill (getpid (), SIGINT);
  167.         return_value = 0;
  168.     }
  169.     return return_value;
  170. }
  171.